package cn.myframe.controller.sys;

import cn.myframe.controller.AbstractController;
import cn.myframe.controller.BaseController;
import cn.myframe.entity.bus.BusCompanyEntity;
import cn.myframe.entity.sys.*;
import cn.myframe.log.LogPojo;
import cn.myframe.redis.RedisService;
import cn.myframe.service.BaseService;
import cn.myframe.service.bus.BusCompanyService;
import cn.myframe.service.sys.*;
import cn.myframe.utils.*;
import cn.myframe.utils.annotation.CheckSubmit;
import cn.myframe.utils.annotation.IgnoreAuth;
import cn.myframe.utils.annotation.SysLog;
import cn.myframe.utils.aop.AssociateData;
import cn.myframe.utils.authorize.EncryptData;
import cn.myframe.utils.authorize.HardwareUtil;
import cn.myframe.utils.authorize.HtmlUtil;
import cn.myframe.utils.authorize.PjAuthorizeUtil;
import cn.myframe.utils.core.PageUtils;
import cn.myframe.utils.core.Query;
import cn.myframe.utils.core.R;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

//import cn.myframe.annotation.IgnoreAuth;

/**
 * 系统用户
 * 
 * @author ynz
 * @email ynz@myframe.cn
 * @date 2016年10月31日 上午10:40:10
 */
@RestController
@RequestMapping("/sys/sysuser")
//@IgnoreAuth
public class SysUserController extends AbstractController implements BaseController<SysUserEntity,BaseService<SysUserEntity>> {
	@Autowired
	private SysUserService sysUserService;
	@Autowired
	private BusCompanyService busCompanyService;
	@Autowired
	private SysUserInfoService sysUserInfoService;
	@Autowired
	private SysParameterService sysParameterService;
	@Autowired
	private SysShellService sysShellService;
	@Autowired
	private SysLogService sysLogService;
	@Autowired
	private RedisService redisService;
	public static final String authFileName = "authorize.dat";
	
	 /**
     * nginx访问地址
     */
    /*@Value("${upload.NGINX_PATH:127.0.0.1:8090}")
    public  String NGINX_PATH;*/
    
	@ResponseBody
	@RequestMapping(value = "/list",method = {RequestMethod.GET})
	@RequiresPermissions("sysuser:list")
	public R lists(@RequestParam Map<String, Object> params){
		Query query = new Query(params);
		PageUtils pageUtil = getService().queryPage(query);
		for (Object obj : pageUtil.getList()) {
			SysUserEntity userEntity = (SysUserEntity) obj;
			BusCompanyEntity busCompanyEntity = busCompanyService.queryObject(userEntity.getCompanyNo());
			if (busCompanyEntity != null) userEntity.setCompanyName(busCompanyEntity.getCompanyName());
		}
		return R.ok().put("page", pageUtil);
	}
	
	/**
	 * 信息
	 */
	@RequestMapping("/info/{id}")
	public R info(@PathVariable("id") Long id){
		SysUserEntity userEntity = getService().queryObject(id);
		userEntity.setPassword(null);
		BusCompanyEntity busCompanyEntity = busCompanyService.queryObject(userEntity.getCompanyNo());
		if (busCompanyEntity != null) userEntity.setCompanyName(busCompanyEntity.getCompanyName());
		return R.ok().put("user", userEntity);
	}
	/**
	 * 获取登录的用户信息
	 */
	@RequestMapping("/info")
	@IgnoreAuth
	public R info(){
		String NGINX_PATH = "";
		SysParameterEntity parameter = sysParameterService.queryByKey("NGINX_PATH");
		if(parameter != null){
			NGINX_PATH = parameter.getParamValue();
		}
		SysUserEntity entity = sysUserService.queryObject(getUserId());
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("companyId", String.valueOf(entity.getCompanyNo()));
		//查询列表数据
        Query query = new Query(params);
        List<SysUserInfoEntity> sysUserInfoList = sysUserInfoService.queryList(query);
        String icon = "";
        if(sysUserInfoList!=null && sysUserInfoList.size()>0){
        	icon = sysUserInfoList.get(0).getIcon();
        }
        if(StringUtils.isNotEmpty(icon)){
        	icon = NGINX_PATH+icon;
        }
		return R.ok().put("user", entity).put("icon", icon);
	}
	
	@RequestMapping("/save")
	@RequiresPermissions("sysuser:save")
	public R save(@RequestBody SysUserEntity user){
		//ValidatorUtils.validateEntity(user, AddGroup.class);
		sysUserService.save(user);
		return R.ok();
	}

	/**
	 * 修改用户
	 */
	@RequestMapping("/update")
	@RequiresPermissions("sysuser:update")
	public R update(@RequestBody SysUserEntity user){
		//ValidatorUtils.validateEntity(user, UpdateGroup.class);

		sysUserService.update(user);
		return R.ok();
	}
	
	@RequestMapping("/audit/8")
	@CheckSubmit(AssociateData.ROLE_USER + "," + AssociateData.COMPANY_USER)
	@RequiresPermissions("sysuser:used")
	public R used(@RequestBody Long[] ids) {
		sysUserService.updateStatus(ids, 8);
		return R.ok();
	}

	@RequestMapping("/audit/9")
	@RequiresPermissions("sysuser:stopUsed")
	public R stopUsed(@RequestBody Long[] ids) {
		sysUserService.updateStatus(ids, 9);
		return R.ok();
	}

	@RequestMapping("/delete")
	@RequiresPermissions("sysuser:delete")
	public R delete(@RequestBody Long[] ids) {
		sysUserService.deleteByIds(ids);
		return R.ok();
	}
	
	/**
     * 校验用户名称
     */
    @RequestMapping("/checkRepeat")
    @ResponseBody
    public String checkRepeat(String username,String userId){
        boolean result = true;
        int count = sysUserService.checkRepeat(username, userId);
        if(count > 0 ){
            result = false;
        }
        return "{\"valid\":" + result + "}";
    }
	/**
	 * 修改登录用户密码
	 */
	@SysLog("修改密码")
	@RequestMapping("/password")
	@IgnoreAuth
	public R password(String password, String newPassword){
		if(StringUtils.isEmpty(password)){
			return R.error("原密码不能为空");
		}
		//更新密码
		int count = sysUserService.updatePassword(getUserId(), password, newPassword);
		if(count == 0){
			return R.error("原密码不正确");
		}
		
		HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
		LogPojo logPojo = new LogPojo();
		logPojo.setIp(IPUtils.getIpAddr(request));
		logPojo.setType(2);
		logPojo.setOperation("changePassword");
		logPojo.setMethod("cn.myframe.controller.sys.SysUserController.password()");
		logPojo.setClassName("SysUserController");
		SysLogEntity sysLogEntity = new SysLogEntity(logPojo);
		sysLogEntity.setUsername(ShiroUtils.getUserEntity().getUsername());
		sysLogEntity.setCreateBy(ShiroUtils.getUserEntity().getUserId());
		sysLogEntity.setCreateDate(new Date());
		sysLogService.insert(sysLogEntity);

		//退出
		ShiroUtils.logout();
		
		return R.ok();
	}
	
	public SysUserService getService(){
		return sysUserService;
	}
    /**
	 * 修改登录用户语言
	 */
	@RequestMapping("/changeLanguage")
	public R changeLanguage(String language){
		sysUserService.updateLanguage(getUserId(),language);
		ShiroUtils.getUserEntity().setLanguage(language);
		return R.ok();
	}

	/**
	 * 上传证书
	 */
	@IgnoreAuth
	@RequestMapping(value = "/uploadMultipleFile", method = RequestMethod.POST, produces = "application/json;charset=utf8")
	@ResponseBody
	public R uploadMultipleFileHandler(@RequestParam("file") MultipartFile[] files) throws IOException {
		String desc = "上传成功";
        /*String classPath = PjAuthorizeUtil.class.getResource("/").getPath()
                .replaceAll("%20", " ");*/
		String path = ResourceUtils.getURL("classpath:application.yml").getPath();
		String classPath = StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(path, "/"), "/").replace("file:", "") + File.separator;
		for (int i = 0; i < files.length; i++) {
			MultipartFile file = files[i];
			if (!file.isEmpty()) {
				InputStream in = null;
				OutputStream out = null;
				try {
					File dir = new File(classPath);
					if (!dir.exists())
						dir.mkdirs();
					String pathName = classPath + authFileName;
					File serverFile = new File(pathName);

					in = file.getInputStream();
					out = new FileOutputStream(serverFile);
					byte[] b = new byte[1024];
					int len = 0;
					while ((len = in.read(b)) > 0) {
						out.write(b, 0, len);
					}
					out.close();
					in.close();
					PjAuthorizeUtil.initAuthInfo();

					//处理分发授权地址
					dealAdsAddress(pathName);
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (out != null) {
						out.close();
						out = null;
					}

					if (in != null) {
						in.close();
						in = null;
					}
				}

			} else {

			}

		}
		return R.ok().put("desc", desc);
	}

	/**
	 * 生成注册文件
	 */
	@IgnoreAuth
	@RequestMapping("/createRegistFile")
	public void createRegistFile(HttpServletRequest request,HttpServletResponse response) throws IOException
	{
		String mac = HardwareUtil.getMac();
		EncryptData enc = new EncryptData();
		String registInfo = enc.encrypt("myframe" + mac);
		byte[] data = registInfo.getBytes();
		HtmlUtil.outPutFile("regist.dat", registInfo, response);
	}

	/**
	 * 获取授权文件内容
	 * @throws FileNotFoundException
	 */
	@IgnoreAuth
	@RequestMapping(value = "/getAuthorizeInfo", method = RequestMethod.GET, produces = "application/json;charset=utf8")
	@ResponseBody
	public R getAuthorizeInfo(HttpServletRequest request ) throws FileNotFoundException
	{
		String path = ResourceUtils.getURL("classpath:application.yml").getPath();
		String classPath = StringUtils.substringBeforeLast(StringUtils.substringBeforeLast(path, "/"), "/").replace("file:", "") + File.separator;
		try {
			File file = new File(classPath + authFileName);
			//没有授权文件
			if(!file.exists()){
				return R.error("notAuthorized");
			}
			String authorizeInfo = FileUtils.readFileContent(classPath + authFileName);
			if (authorizeInfo != null && !authorizeInfo.isEmpty()) {
				EncryptData en = new EncryptData();
				authorizeInfo = en.decrypt(authorizeInfo);
				if (authorizeInfo.startsWith("myframe")) {
					String[] array = authorizeInfo.split(";");

					String[] fmacArray = array[0].substring(5)
							.split("&");
					String[] macArray = HardwareUtil.getMac()
							.split("&");

					boolean correct = matchMac(fmacArray,macArray);
					if (!correct) {
						return R.error("wrongMac");
					}

					if (array != null && array.length > 3) {
						String startStr = array[3];
						String endStr = array[1];
						Date startDate = new Date(Long.parseLong(startStr));
						Date endDate = new Date(Long.parseLong(endStr));
						String startTime = DateUtils.format(startDate);
						String endTime = DateUtils.format(endDate);
						String adsAddress = "";
						if(array.length > 4){
							adsAddress = array[4];
						}
						return R.ok().put("startTime", startTime).put("endTime", endTime).put("ads", adsAddress);
					}else{
						return R.error("notAuthorized");
					}
				}
			}
		} catch (Exception e) {

		}
		return R.ok();
	}

	public boolean matchMac(String[] fmacArray,String[] macArray){
		boolean correct = true, find = false;
		for (String mac : macArray) {
			if (mac != null && !mac.isEmpty()) {
				find = false;
				for (String fmac : fmacArray) {
					if (mac.equals(fmac)) {
						find = true;
						break;
					}
				}
				if(!find){
					correct = false;
					break;
				}
			}
		}
		return correct;
	}

	public void dealAdsAddress(String pathName){
		try {
			String authorizeInfo = FileUtils.readFileContent(pathName);
			if (authorizeInfo != null && !authorizeInfo.isEmpty()) {
				EncryptData en = new EncryptData();
				authorizeInfo = en.decrypt(authorizeInfo);
				if (authorizeInfo.startsWith("myframe")) {
					String[] array = authorizeInfo.split(";");

					String[] fmacArray = array[0].substring(5)
							.split("&");
					String[] macArray = HardwareUtil.getMac()
							.split("&");

					boolean correct = matchMac(fmacArray,macArray);
					if (correct) {
						//查找当前存在系统中的所有分发数据
						List<SysShellEntity> list = sysShellService.selectAds();
						Set<String> adsSet = new HashSet<>();
						if(list != null && list.size() > 0){
							for(SysShellEntity shell : list){
								adsSet.add(shell.getIp());
							}
						}
						String adsAddre = "";
						if (array != null && array.length > 4) {
							String passKey = "myframe.cn";
							String adsStr = array[4];
							if(StringUtils.isNotEmpty(adsStr)){
								String[] adsAddress = adsStr.split(",");
								Set<String> set = new HashSet<String>();
								for(String adsAddr : adsAddress){
									if(adsSet.contains(adsAddr)){
										//删除包含的，留下旧授权该删除的数据
										adsSet.remove(adsAddr);
									}else{
										//留下需保存的
										set.add(adsAddr);
									}
								}
								SysShellEntity shell = new SysShellEntity();
								for(String addr : set){
									shell.setServerName(addr);
									shell.setIp(addr);
									shell.setType(2);
									sysShellService.save(shell);
								}
								for(String ip : adsSet){
									sysShellService.deleteByIp(ip);
								}
								adsAddre = AESSecurityUtil.encrypt(adsStr, passKey);
							}
						}else{
							for(String ip : adsSet){
								sysShellService.deleteByIp(ip);
							}
						}
						String key = "systemAds:";
						redisService.set(key, adsAddre); //设置redis中的授权分发地址
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}




}
